#!/usr/bin/env julia

using Pkg
Pkg.activate(joinpath(@__DIR__, ".."), io=devnull)

using Dates
using Statistics
using JSON3
using Printf

using GSICoreAnalysis
using GSICoreAnalysis.DataIO: RadianceBUFRConfig, read_radiance_bufr
using GSICoreAnalysis.DataIO.RadianceBUFRReader: summarize_radiance_observations

function parse_args()
    bufr_path = get(ENV, "GSICORE_RADIANCE_FILE", "")
    max_obs = parse(Int, get(ENV, "GSICORE_MAX_OBS", "5000"))
    channel_subset = get(ENV, "GSICORE_CHANNEL_SUBSET", "")

    if !isempty(ARGS)
        bufr_path = ARGS[1]
    end

    if isempty(bufr_path)
        error("Provide BUFR path via argument or GSICORE_RADIANCE_FILE env var")
    end

    channels = isempty(channel_subset) ? nothing : parse.(Int, split(channel_subset, ','))

    return bufr_path, max_obs, channels
end

function format_range(label, values)
    lo = minimum(values)
    hi = maximum(values)
    @printf("  %-12s %8.2f to %8.2f\n", label, lo, hi)
end

format_stat(x::AbstractFloat) = isfinite(x) ? @sprintf("%7.2fK", x) : "    NaN "

function sanitize_summary(obj)
    if obj isa AbstractFloat
        return isfinite(obj) ? obj : nothing
    elseif obj isa DateTime
        return Dates.format(obj, dateformat"yyyy-mm-ddTHH:MM:SS")
    elseif obj isa Dict
        return Dict(k => sanitize_summary(v) for (k, v) in obj)
    elseif obj isa Vector
        return [sanitize_summary(v) for v in obj]
    elseif obj isa Tuple
        return [sanitize_summary(v) for v in obj]
    else
        return obj
    end
end

function main()
    bufr_path, max_obs, channels = parse_args()

    println(repeat("=", 80))
    println("Satellite Radiance Real BUFR Demonstration")
    println(repeat("=", 80))

    println("Input BUFR : $bufr_path")
    println("Max Obs    : $max_obs")
    if channels === nothing
        println("Channels   : all")
    else
        println("Channels   : $(join(channels, ", "))")
    end

    config = RadianceBUFRConfig(
        max_obs=max_obs,
        channel_subset=channels,
        verbose=true,
        angle_limit=65.0
    )

    t_start = time()
    obs = read_radiance_bufr(bufr_path; config=config)
    elapsed = time() - t_start

    println("\nDecoded $(size(obs.brightness_temp, 2)) observation sites " *
            "with $(length(obs.channels)) channels in $(round(elapsed, digits=2)) s")

    summary = summarize_radiance_observations(obs)

    println("\nInstrument : $(summary["instrument"]) on $(summary["satellite"])\n")
    println("Observation Totals")
    println("  Locations : $(summary["n_observations"])")
    println("  Channels  : $(summary["n_channels"]) -> $(join(summary["channels"], ", "))")

    println("\nSpatial Coverage")
    lat_range = summary["spatial_coverage"]["lat_range"]
    lon_range = summary["spatial_coverage"]["lon_range"]
    @printf("  Latitude  : %8.2f to %8.2f\n", lat_range[1], lat_range[2])
    @printf("  Longitude : %8.2f to %8.2f\n", lon_range[1], lon_range[2])

    geom = summary["geometry"]
    @printf("  Zenith    : %8.2f to %8.2f (mean %.2f)\n",
            geom["zenith_angle_range"][1], geom["zenith_angle_range"][2],
            geom["mean_zenith_angle"])

    time_range = summary["time_range"]
    println("\nTime Range")
    println("  $(time_range[1]) -> $(time_range[2])")

    println("\nChannel Statistics (first 10)")
    chan_stats = summary["channel_statistics"]
    printed = 0
    for ch in summary["channels"]
        stats = chan_stats[ch]
        mean_str = format_stat(stats["mean_tb"])
        std_str = format_stat(stats["std_tb"])
        min_str = format_stat(stats["min_tb"])
        max_str = format_stat(stats["max_tb"])
        println("  ch $(lpad(string(ch), 2))  mean=$mean_str  std=$std_str  min=$min_str  max=$max_str")
        printed += 1
        printed >= 10 && break
    end

    results_dir = joinpath(@__DIR__, "..", "results")
    isdir(results_dir) || mkpath(results_dir)
    json_path = joinpath(results_dir, "radiance_real_summary.json")
    cleaned = sanitize_summary(summary)
    JSON3.write(json_path, cleaned)
    println("\nSummary written to $json_path")

    println("\nDone.")
end

main()
